<script setup>
import { ref, onMounted, inject } from "vue";
import { ElMessage } from "element-plus";
import { Delete, Edit, Search, Close, Check, Grid } from "@element-plus/icons-vue";
import { useRouter } from "vue-router";
import { BREADCRUMBS, SEXS, SEX_OPTIONS, AVATAR } from "@/plugins/global";

const axios = inject("axios"), router = useRouter();

// ---- 组件加载：重设面包屑/计算数据表格高度/查询员工集。
onMounted(() => {
  BREADCRUMBS.splice(0, BREADCRUMBS.length,
    { label: "员工列表", path: "/home/staff_list" }
  );
  queryStaffs();
});
// ---- 查询员工集。
const staffCondition = ref({
  "staffIdOrder": "ASC",
  "staffAccountFuzzy": null,
  "staffPhoneNumberFuzzy": null,
  "staffNameFuzzy": null,
  "staffGteBirthdayStr": null,
  "staffLteBirthdayStr": null
});
const staffTotal = ref(null), staffPages = ref({
  "page": 1,
  "num": 10,
  "total": true
})
const staffs = ref([]);
const queryStaffs = () => {
  axios.get("/api/cms-web/staff/queries", {
    params: {
      "page": staffPages.value.page,
      "num": staffPages.value.num,
      "total": staffPages.value.total,
      "staffIdOrder": staffCondition.value.staffIdOrder,
      "staffAccountFuzzy": staffCondition.value.staffAccountFuzzy,
      "staffPhoneNumberFuzzy": staffCondition.value.staffPhoneNumberFuzzy,
      "staffNameFuzzy": staffCondition.value.staffNameFuzzy,
      "staffGteBirthdayStr": staffCondition.value.staffGteBirthdayStr,
      "staffLteBirthdayStr": staffCondition.value.staffLteBirthdayStr
    }
  }).then((response) => {
    if (response.data.success) {
      staffs.value = response.data.data.data;
      staffTotal.value = response.data.data.total;
    } else {
      ElMessage.error(response.data.message);
    }
  });
};
// ---- 查询排序员工集。
const queryOrderStaffs = ({ column, prop, order }) => {
  if (prop === "staffId") {
    staffCondition.value.staffIdOrder = order ? (order === "ascending" ? "ASC" : "DESC") : null;
  }
  queryStaffs();
};
// ---- 插入/更新员工准备：展示弹窗，并重置初始员工。
const staffUpsertDialogModel = ref(false), staffUpsertFormRef = ref(null);
const staffUpsert = ref({
  "staffId": null,
  "staffAccount": null,
  "phoneNumber": null,
  "name": null,
  "sex": -1,
  "birthdayStr": null,
  "avatar": AVATAR
});
const upsertStaffPrepare = (staffId) => {
  staffUpsertDialogModel.value = true;
  // ---- 重置员工插入表单的状态&数据。
  if (staffUpsertFormRef.value) {
    staffUpsertFormRef.value.resetFields();
  }
  if (staffId == null) {
    // ---- 插入准备：员工ID重置。员工ID需要特殊处理一下，因为ID输入框在插入时不存
    // 在，因此可能无法被上游的staffUpsertFormRef.value.resetFields();代码重置。
    staffUpsert.value.staffId = null;
  } else {
    // ---- 更新准备：获取指定员工并与表单中展示。
    axios.get(`/api/cms-web/staff/get?staffId=${staffId}`).then(response => {
      if (response.data.success) {
        const data = response.data.data;
        staffUpsert.value.staffId = data.staffId;
        staffUpsert.value.staffAccount = data.staffAccount;
        staffUpsert.value.phoneNumber = data.phoneNumber;
        staffUpsert.value.name = data.name;
        staffUpsert.value.sex = data.sex;
        staffUpsert.value.birthdayStr = data.birthdayStr;
        staffUpsert.value.avatar = data.avatar != null ? data.avatar : AVATAR;
      } else {
        ElMessage.error(response.data.message);
      }
    });
  }
};
// ---- 插入/更新员工确认：远程插入/更新员工并关闭弹窗。
const staffUpsertFormRules = ref({
  staffId: [{ required: true, message: "请输入ID！", trigger: "blur" }],
  staffAccount: [{ required: true, message: "请输入账号！", trigger: "blur" }],
  name: [{ required: true, message: "请输入名称！", trigger: "blur" }],
  phoneNumber: [{ required: true, message: "请输入手机号码！", trigger: "blur" }],
  sex: [{ required: true, message: "请输入性别！", trigger: "blur" }],
});
const upsertStaffConfirm = () => {
  staffUpsertFormRef.value.validate((valid) => {
    if (valid) {
      // ---- 插入员工。
      if (staffUpsert.value.staffId === null) {
        axios.post("/api/cms-web/oauth/insert", {
          "staffAccount": staffUpsert.value.staffAccount,
          // ---- 默认密码。
          "password": "123456789",
          "phoneNumber": staffUpsert.value.phoneNumber,
          "name": staffUpsert.value.name,
          "sex": staffUpsert.value.sex,
          "birthdayStr": staffUpsert.value.birthdayStr,
          "avatar": staffUpsert.value.avatar
        }).then((response) => {
          if (response.data.success) {
            ElMessage.success("插入成功！");
            queryStaffs();
            staffUpsertDialogModel.value = false;
          } else {
            ElMessage.error(response.data.message);
          }
        });
      } else {
        // ---- 更新员工。
        axios.put("/api/cms-web/staff/update", {
          "staffId": staffUpsert.value.staffId,
          "phoneNumber": staffUpsert.value.phoneNumber,
          "name": staffUpsert.value.name,
          "sex": staffUpsert.value.sex,
          "birthdayStr": staffUpsert.value.birthdayStr,
          "avatar": staffUpsert.value.avatar
        }).then((response) => {
          if (response.data.success) {
            ElMessage.success("更新成功！");
            queryStaffs();
            staffUpsertDialogModel.value = false;
          } else {
            ElMessage.error(response.data.message);
          }
        });
      }
    }
  });
};
// ---- 禁用员工：禁用/启用指定员工。
const disableStaff = (staff, disable) => {
  axios.put("/api/cms-web/oauth/disable", {
    "staffId": staff.staffId,
    "staffAccount": staff.staffAccount,
    "disable": disable
  }).then((response) => {
    if (response.data.success) {
      ElMessage.success(disable ? "禁用成功！" : "启用成功！");
      queryStaffs();
    } else {
      ElMessage.error(response.data.message);
    }
  });
};
// ---- 删除员工准备：展示删除弹框，并记录删除员工。
const staffDeleteDialogDisable = ref(false), staffDelete = ref(null);
const deleteStaffPrepare = (staff) => {
  staffDeleteDialogDisable.value = true;
  staffDelete.value = staff;
};
// ---- 删除员工确认：正式删除员工，并隐藏删除弹窗。
const deleteStaffConfirm = () => {
  axios.delete("/api/cms-web/oauth/delete", {
    params: {
      "staffId": staffDelete.value.staffId,
      "staffAccount": staffDelete.value.staffAccount
    }
  }).then((response) => {
    if (response.data.success) {
      ElMessage.success("删除成功！");
      queryStaffs();
      staffDeleteDialogDisable.value = false;
      staffDelete.value = null;
    } else {
      ElMessage.error(response.data.message);
    }
  });
};
</script>

<template>
  <div class="staff-page-div-class">
    <!-- 员工条件域 -->
    <div style="width: 100%;">
      <el-form :inline="true" :model="staffCondition">
        <el-form-item label="账号">
          <el-input v-model="staffCondition.staffAccountFuzzy" :prefix-icon="Search" clearable style="width: 200px" />
        </el-form-item>
        <el-form-item label="手机号码">
          <el-input v-model="staffCondition.staffPhoneNumberFuzzy" :prefix-icon="Search" clearable
            style="width: 200px" />
        </el-form-item>
        <el-form-item label="名称">
          <el-input v-model="staffCondition.staffNameFuzzy" :prefix-icon="Search" clearable style="width: 200px" />
        </el-form-item>
        <el-form-item label="生日">
          <el-date-picker v-model="staffCondition.staffGteBirthdayStr" type="date" placeholder="开始（>=）"
            format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
          <span>&nbsp;&nbsp;~&nbsp;&nbsp;</span>
          <el-date-picker v-model="staffCondition.staffLteBirthdayStr" type="date" placeholder="结束（<=）"
            format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="queryStaffs()">查询</el-button>
          <el-button @click="upsertStaffPrepare(null)">插入</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 员工表格域 -->
    <div class="staff-table-div-class">
      <el-table :data="staffs" height="100%" stripe @sort-change="queryOrderStaffs">
        <el-table-column prop="staffId" label="ID" sortable="custom" align="center" />
        <el-table-column prop="staffAccount" label="账号" align="center" />
        <el-table-column prop="phoneNumber" label="手机号码" align="center" />
        <el-table-column prop="name" label="名称" align="center" />
        <el-table-column label="性别" align="center" width="80px">
          <template #default="scope">
            {{ SEXS[scope.row.sex + 1] }}
          </template>
        </el-table-column>
        <el-table-column prop="birthdayStr" label="生日" align="center" />
        <el-table-column prop="disable" label="禁用" align="center" width="80px">
          <template #default="scope">
            <span>{{ scope.row.disable ? "禁用" : "启用" }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" align="center" width="200px">
          <template #default="scope">
            <el-button type="primary" :icon="Edit" circle @click="upsertStaffPrepare(scope.row.staffId)" />
            <el-button type="success" :icon="Grid" circle
              @click="router.push(`/home/staff_authority/${scope.row.staffAccount}`)" />
            <el-button :icon="Check" circle v-if="scope.row.disable" @click="disableStaff(scope.row, false)" />
            <el-button type="info" :icon="Close" circle v-else @click="disableStaff(scope.row, true)" />
            <el-button type="danger" :icon="Delete" circle @click="deleteStaffPrepare(scope.row)" />
          </template>
        </el-table-column>
      </el-table>
    </div>
    <!-- 员工分页域 -->
    <div class="staff-pagination-div-class">
      <el-pagination background layout="total, prev, pager, next, sizes" size="small" :total="staffTotal"
        v-model:page-size="staffPages.num" @update:page-size="queryStaffs()" :page-sizes="[10, 20, 50, 100]"
        v-model:current-page="staffPages.page" @update:current-page="queryStaffs()" />
    </div>
  </div>
  <!-- 员工插入/更新域 -->
  <el-dialog v-model="staffUpsertDialogModel" width="1000px" style="padding: 20px 40px 25px 40px;">
    <el-form ref="staffUpsertFormRef" :model="staffUpsert" :rules="staffUpsertFormRules" label-position="top"
      require-asterisk-position="right">
      <div style="padding-bottom: 20px; text-align: center">
        <el-avatar :size="120" :src="staffUpsert.avatar" />
      </div>
      <div class="staff-upsert-form-item-class">
        <!-- ID输入框只允许在更新时展示，并且不可写入 -->
        <el-form-item label="ID" prop="staffId" v-if="staffUpsert.staffId != null">
          <el-input v-model="staffUpsert.staffId" style="width: 200px" autocomplete="off" disabled />
        </el-form-item>
        <!-- 更新时账号输入框是不可写入的 -->
        <el-form-item label="账号" prop="staffAccount">
          <el-input v-model="staffUpsert.staffAccount" style="width: 200px" autocomplete="off" disabled
            v-if="staffUpsert.staffId != null" />
          <el-input v-model="staffUpsert.staffAccount" style="width: 200px" autocomplete="off" v-else />
        </el-form-item>
        <el-form-item label="名称" prop="name">
          <el-input v-model="staffUpsert.name" style="width: 200px" autocomplete="off" />
        </el-form-item>
        <el-form-item label="手机号码" prop="phoneNumber">
          <el-input v-model="staffUpsert.phoneNumber" style="width: 200px" autocomplete="off" />
        </el-form-item>
      </div>
      <div class="staff-upsert-form-item-class">
        <el-form-item label="性别" prop="sex">
          <el-select v-model="staffUpsert.sex" placeholder="选择" style="width: 200px">
            <el-option v-for="item in SEX_OPTIONS" :key="item.value" :value="item.value" :label="item.label" />
          </el-select>
        </el-form-item>
        <el-form-item label="生日" prop="birthdayStr">
          <el-date-picker v-model="staffUpsert.birthdayStr" type="date" style="width: 200px" format="YYYY-MM-DD"
            value-format="YYYY-MM-DD" />
        </el-form-item>
      </div>
    </el-form>
    <template #footer>
      <span>
        <el-button @click="staffUpsertDialogModel = false">取消</el-button>
        <el-button type="primary" @click="upsertStaffConfirm()">确定</el-button>
      </span>
    </template>
  </el-dialog>
  <!-- 员工删除域 -->
  <el-dialog header="确认删除" v-model="staffDeleteDialogDisable" width="300px">
    <span>您确定要删除这个员工吗？</span>
    <template #footer>
      <span>
        <el-button @click="staffDeleteDialogDisable = false">取消</el-button>
        <el-button type="primary" @click="deleteStaffConfirm()">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped>
.staff-page-div-class {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 15px;
  width: 100%;
  height: 100%;
  padding: 20px 20px 20px 20px;
}

.staff-table-div-class {
  flex: 1;
  width: 100%;
  overflow: hidden;
}

.staff-pagination-div-class {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  align-items: flex-end;
  width: 100%;
}

.staff-upsert-form-item-class {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}
</style>